package com.irwin.skin;

import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.Nullable;

import java.util.Map;
import java.util.Set;

/**
 * Created by ARES on 2020/1/5.
 */
public abstract class AbstractSPProvider {

    public abstract SharedPreferences getDB();

    /**
     * Initialize shared preferences.
     */
    protected SharedPreferences initDB(Context context, String name, int mode) {
        return context.getSharedPreferences(name, mode);
    }

    /**
     * Convenience method for saving key\value and applying.
     * Only support basic types and String set.
     */
    public void putApply(String key, Object value) {
        SharedPreferences.Editor editor = getDB().edit();
        put(editor, key, value);
        editor.apply();
    }

    /**
     * Do not use this method directly for it does not commit the operation.
     */
    void put(SharedPreferences.Editor editor, String key, Object value) {
        if (value instanceof String) {
            editor.putString(key, (String) value);
        } else if (value instanceof Boolean) {
            editor.putBoolean(key, (Boolean) value);
        } else if (value instanceof Integer) {
            editor.putInt(key, (Integer) value);
        } else if (value instanceof Float) {
            editor.putFloat(key, (Float) value);
        } else if (value instanceof Long) {
            editor.putLong(key, (Long) value);
        } else if (value instanceof Set) {
            editor.putStringSet(key, (Set<String>) value);
        } else {
            throw new UnsupportedOperationException("Unsupported type!");
        }
    }

    /**
     * Convenience method for saving key\value and committing.Only support basic types and String set.
     */
    public void putCommit(String key, Object value) {
        SharedPreferences.Editor editor = getDB().edit();
        put(editor, key, value);
        editor.commit();
    }

    /**
     * Retrieve all values from the preferences.
     */
    public Map<String, ?> getAll() {
        return getDB().getAll();
    }

    /**
     * Retrieve a String value from the preferences.

     * @throws ClassCastException
     */
    @Nullable
    public String getString(String key, @Nullable String defValue) {
        return getDB().getString(key, defValue);
    }

    /**
     * Retrieve a set of String values from the preferences.
     */
    @Nullable
    public Set<String> getStringSet(String key, @Nullable Set<String> defValues) {
        return getDB().getStringSet(key, defValues);
    }

    /**
     * Retrieve an int value from the preferences.
     */
    public int getInt(String key, int defValue) {
        return getDB().getInt(key, defValue);
    }

    /**
     * Retrieve a long value from the preferences.
     */
    public long getLong(String key, long defValue) {
        return getDB().getLong(key, defValue);
    }

    /**
     * Retrieve a float value from the preferences.
     */
    public float getFloat(String key, float defValue) {
        return getDB().getFloat(key, defValue);
    }

    /**
     * Retrieve a boolean value from the preferences.
     */
    public boolean getBoolean(String key, boolean defValue) {
        return getDB().getBoolean(key, defValue);
    }

    /**
     * Checks whether the preferences contains a preference.
     */

    public boolean contains(String key) {
        return getDB().contains(key);
    }

}
